/**
 * @file drv_lan7820.c
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2024-04-22
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#include <stdint.h>
#include "drv_lan7820.h"
#include "at32f435_437_emac.h"

static uint8_t emac_periph_config(void);
static void emac_pins_configure(void);
static void emac_tmr_init(void);

uint8_t emac_init()
{
    emac_pins_configure();
    emac_tmr_init();
    emac_periph_config();
}

/**
 * @brief 初始化EMAC外设
 * 
 * @return uint8_t 0 - 失败
 */
static uint8_t emac_periph_config(void)
{
    crm_periph_clock_enable(CRM_EMAC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_EMACTX_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_EMACRX_PERIPH_CLOCK, TRUE);

    return emac_layer2_configuration();
}

/**
 * @brief EMAC 引脚配置
 * 
 */
static void emac_pins_configure(void)
{
    gpio_init_type gpio_init_struct = {0};

    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);

    /* pa2 -> mdio */
    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE2, GPIO_MUX_11);
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pins = GPIO_PINS_2;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &gpio_init_struct);

    /* pc1 -> mdc */
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE1, GPIO_MUX_11);
    gpio_init_struct.gpio_pins = GPIO_PINS_1;
    gpio_init(GPIOC, &gpio_init_struct);

    /*
    pg13 -> tx_d0
    pg14 -> tx_d1
    pb11 -> tx_en
    */
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE11, GPIO_MUX_11);
    gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE13, GPIO_MUX_11);
    gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE14, GPIO_MUX_11);
    gpio_init_struct.gpio_pins = GPIO_PINS_13 | GPIO_PINS_14;
    gpio_init(GPIOG, &gpio_init_struct);

    gpio_init_struct.gpio_pins = GPIO_PINS_11;
    gpio_init(GPIOB, &gpio_init_struct);

    /*
    pa7  -> rx_dv
    pc4  -> rx_d0
    pc5 -> rx_d1
    */
    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_11);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE4, GPIO_MUX_11);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE5, GPIO_MUX_11);
    gpio_init_struct.gpio_pins = GPIO_PINS_4;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init(GPIOC, &gpio_init_struct);

    gpio_init_struct.gpio_pins = GPIO_PINS_7;
    gpio_init(GPIOA, &gpio_init_struct);

    gpio_init_struct.gpio_pins = GPIO_PINS_5;
    gpio_init(GPIOC, &gpio_init_struct);
    /*
    pa1  -> ref_clk
    */
    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_11);
    gpio_init_struct.gpio_pins = GPIO_PINS_1;
    gpio_init(GPIOA, &gpio_init_struct);

}

/**
 * @brief EMAC定时器配置
 * 
 */
static void emac_tmr_init(void)
{
    crm_clocks_freq_type crm_clocks_freq_struct = {0};
    crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);

    crm_clocks_freq_get(&crm_clocks_freq_struct);
    /* tmr1 configuration */
    /* time base configuration */
    /* systemclock/24000/100 = 100hz */
    tmr_base_init(TMR6, 99, (crm_clocks_freq_struct.ahb_freq / 10000) - 1);
    tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);

    /* overflow interrupt enable */
    tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE);

    /* tmr1 overflow interrupt nvic init */
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
    nvic_irq_enable(TMR6_DAC_GLOBAL_IRQn, 0, 0);
    tmr_counter_enable(TMR6, TRUE);
}
